/*
 * Provides functions for controlling the system time based on Internet time
 * by using some of the general time and date functions in TimeDate.c
 */
#include "TimeDate.h"
#include "Types.h"
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZClock.h"
#include <stdio.h>
#include "domain.h";
#include <SNTPClient.h>
#include "eeprom.h"
#include <ztptcp.h>
#include "date.h"
#include <netif.h>


// The <SNTPClient.h> header does not contain the function declaration that it should, 
//but the libraries have it so I just declare it as extern
extern INT16 ztpSNTPClient( INT8 *targetIPAddress, INT16 portNum );

#define SNTP_PORT 123


// Information found here: http://www.dxing.com/utcgmt.htm


void convertToStandardTime(time_zone_t, BOOL);

extern struct commonServers csTbl;


/*
 * Public function to set the system time to the Internet time 
 * It leverages the Simple Network Time Protocol client built into the Zilog ZTP
 * by querying internet time servers and adjust the system time
 *
 * Note that this algorithm is very dependent on the fact that the 
 * system clock time is set correctly to today's date and time
 *
 * Params:
 *		none
 *
 * Returns:
 * 		Whether or not the time was updates correctly
 *		SUCCESS or GENERAL_ERROR
 */
error_t getInternetTime()
{
	UINT32 timeServerIP;
	INT8 stringIP[16];
	eeprom_settings_t allSettings;

	eepromGetSettings(&allSettings);
	timeServerIP = name2ip(allSettings.timeSettings.timeServerAddress);
	
	if(timeServerIP == SYSERR)
	{
		return GENERAL_ERROR;
	}
	
	//Convert to dot string
	ip2dot(stringIP, timeServerIP);	

	// Copy the IP into csTbl for time_rqest to use
	strcpy(csTbl.timeserver, stringIP);
	strcpy(csTbl.NetworkTimeServer, stringIP);

	if(time_rqest() != OK)
	{
		return GENERAL_ERROR;
	}

	convertToStandardTime(allSettings.timeSettings.timeZone, allSettings.timeSettings.daylightSavingEnabled);
	return SUCCESS;
}


void convertToStandardTime(time_zone_t timeZone, BOOL daylightSavingEnabled)
{
	RZK_CLOCKPARAMS_t sysTime;
	int hour;
	int newHour;
	int newDate;
	int newMonth;
	int newYear;

	RZKGetClock(&sysTime);
	hour = sysTime.uCurr_Hour;

	//At first, we assume that we won't be wrapping backwards on the day, month or year (just adjust hours)
	// We will changes these values only if necessary
	newDate = sysTime.uCurr_Date;
	newMonth = sysTime.uCurr_Month;
	newYear = sysTime.uCurr_Year;
	
	// Now adjust the hours
	newHour = hour + timeZone;

	if(daylightSavingEnabled == TRUE)
	{
		if(inDaylightSaving(newDate, newMonth, newYear) == TRUE)
		{
			//Add one to the hour
			newHour++;
		}
	}

	if(newHour < 0)
	{
		// We are in a time zone who's date is 1 less than UTC
		newHour = 23; //We wrapped back to 23:XX from the day before
		newDate = sysTime.uCurr_Date - 1;
		if(newDate == 0)
		{
			// This wrapped back to the previous month
			newDate = getLastDayInMonth(sysTime.uCurr_Month, sysTime.uCurr_Year);
			newMonth = sysTime.uCurr_Month - 1;
			if(newMonth == 0)
			{
				//We wrapped back to the previous year
				newMonth = 12;
				newYear = sysTime.uCurr_Year - 1;
			}
		}
	}
	else
	{
		// This will never happen in any US time zones so
		// I am not going to complete this section
	}

	sysTime.uCurr_Hour = newHour;
	sysTime.uCurr_Date = newDate;
	sysTime.uCurr_Month = newMonth;
	sysTime.uCurr_Year = newYear;

	RZKSetClock(&sysTime);

	printf("Time set to:\n");
		printf("\tYear:%d\n",sysTime.uCurr_Year);
		printf("\tMonth:%d\n",sysTime.uCurr_Month);
		printf("\tDay:%d\n",sysTime.uCurr_Date);
		printf("\tHour:%d\n",sysTime.uCurr_Hour);
		printf("\tMinute:%d\n",sysTime.uCurr_Minute);
}